package com.restphp.java.hashdb;

import com.restphp.java.hashdb.core.HashDbCore;
import com.restphp.java.hashdb.dcs.DeleteFromCluster;
import com.restphp.java.hashdb.dcs.GetFromCluster;
import com.restphp.java.hashdb.dcs.HashDbClusterConfig;
import com.restphp.java.hashdb.dcs.SetToCluster;
import com.restphp.java.hashdb.dcs.server.HashDbClusterServer;

/**
 * Hash DB.
 * Created by sofical on 2020/8/3.
 */
public class HashDb {
    private HashDbConfig hashDbConfig;
    final private String defaultDbName = "default";
    private String table = defaultDbName;
    private HashDbClusterConfig clusterConfig = null;

    /**
     * 普通单列模式，默认选择默认表：default.
     * @param config 数据落地文件配置.
     */
    public HashDb(HashDbConfig config) {
        this.hashDbConfig = config;
        HashDbCore.startup(this.hashDbConfig.getDbRoot(), this.hashDbConfig.getSaveInterval());
    }

    /**
     * 普通单列模式，初始化选中指定表.
     * @param config 数据落地文件配置.
     * @param table 表名.
     */
    public HashDb(HashDbConfig config, String table) {
        this.hashDbConfig = config;
        this.table = table;
        HashDbCore.startup(this.hashDbConfig.getDbRoot(), this.hashDbConfig.getSaveInterval());
    }

    /**
     * 群集模式，并选中默认表：default.
     * @param config 数据落地文件配置.
     * @param clusterConfig 群集配置.
     */
    public HashDb(HashDbConfig config, HashDbClusterConfig clusterConfig) {
        this.hashDbConfig = config;
        this.clusterConfig = clusterConfig;
        HashDbCore.startup(this.hashDbConfig.getDbRoot(), this.hashDbConfig.getSaveInterval());
        this.startupServer();
    }

    /**
     * 群集模式，初始化选中指定表
     * @param config 数据落地文件配置.
     * @param table 表名.
     * @param clusterConfig 群集配置.
     */
    public HashDb(HashDbConfig config, String table, HashDbClusterConfig clusterConfig) {
        this.hashDbConfig = config;
        this.table = table;
        this.clusterConfig = clusterConfig;
        HashDbCore.startup(this.hashDbConfig.getDbRoot(), this.hashDbConfig.getSaveInterval());
        this.startupServer();
    }

    /**
     * 启动群集服务.
     */
    private void startupServer() {
        HashDbClusterServer clusterServer = new HashDbClusterServer(this.clusterConfig);
        clusterServer.startup();
    }

    /**
     * 选择默认表.
     * @return HashDb.
     */
    public HashDb select() {
        this.table = defaultDbName;
        return this;
    }

    /**
     * 选择表.
     * @param table table.
     * @return HashDb.
     */
    public HashDb select(String table) {
        this.table = table;
        return this;
    }

    /**
     * 获取当前表名.
     * @return 表名.
     */
    public String getTableName() {
        return this.table;
    }

    /**
     * 保存.
     * @param key 键名.
     * @param value 值.
     */
    public HashDb set(String key, Object value) {
        return this.set(key, value, 0);
    }

    /**
     * 保存.
     * @param key 键名.
     * @param value 值.
     * @param timeout 超时时间.
     */
    public HashDb set(String key, Object value, Integer timeout) {
        SetToCluster toCluster = new SetToCluster(this.clusterConfig);
        toCluster.set(this.hashDbConfig.getDbRoot(), table, key, value, timeout);
        return this;
    }

    /**
     * 获取值.
     * @param key 键名.
     * @return 值.
     */
    public String get(String key) {
        return get(key, String.class);
    }

    public <T> T get(String key, Class<T> tClass) {
        GetFromCluster getFromCluster = new GetFromCluster(clusterConfig);
        return getFromCluster.get(this.hashDbConfig.getDbRoot(), table, key, tClass);
    }

    /**
     * 删除.
     * @param key 键名.
     */
    public HashDb delete(String key) {
        DeleteFromCluster deleteFromCluster = new DeleteFromCluster(clusterConfig);
        deleteFromCluster.delete(this.hashDbConfig.getDbRoot(), table, key);
        return this;
    }
}
